1 |
一、基础用法
awk
是处理文本文件的一个应用程序,几乎所有 Linux 系统都自带这个程序。
它依次处理文件的每一行,并读取里面的每一个字段。对于日志、CSV 那样的每行格式相同的文本文件,awk
可能是最方便的工具。
awk
的基本用法就是下面的形式。
1 | # 格式 |
上面示例中,demo.txt
是awk
所要处理的文本文件。前面单引号内部有一个大括号,里面就是每一行的处理动作print $0
。其中,print
是打印命令,$0
代表当前行。因此上面命令是把每一行原样打印出来。
awk
会根据空格和制表符,将每一行分成若干字段,依次用$1
、$2
、$3
代表第一个字段、第二个字段、第三个字段等等。
1 | $ echo 'this is a test' | awk '{print $3}' |
下面,为了便于举例,我们把/etc/passwd
文件保存成demo.txt
。
1 | root:x:0:0:root:/root:/usr/bin/zsh |
这个文件的字段分隔符是冒号(:
),所以要用-F
参数指定分隔符为冒号
1 | $ awk -F ':' '{ print $1 }' demo.txt |
二、变量
数字
:第几个字段(从1开始)NF
:当前行有多少个字段,因此$NF
就代表最后一个字段NR
:表示当前处理的是第几行。FILENAME
:当前文件名FS
:字段分隔符,默认是空格和制表符。RS
:行分隔符,用于分割每一行,默认是换行符。OFS
:输出字段的分隔符,用于打印时分隔字段,默认为空格。ORS
:输出记录的分隔符,用于打印时分隔记录,默认为换行符。OFMT
:数字输出的格式,默认为%.6g
。
变量NF
表示当前行有多少个字段,因此$NF
就代表最后一个字段;$(NF-1)
代表倒数第二个字段。
1
2
3 > $ echo 'this is a test' | awk '{print $NF, $(NF-1)}' # print中的逗号是以空格分隔的意思
> test a
>
变量NR
表示当前处理的是第几行。
1
2
3
4
5
6
7 > $ awk -F ':' '{print NR ") " $1}' demo.txt
> 1) root
> 2) daemon
> 3) bin
> 4) sys
> 5) sync
>
上面代码中,print
命令里面,如果原样输出字符,要放在双引号里面
三、函数
常用函数如下
toupper()
:字符转为大写tolower()
:字符转为小写length()
:返回字符串长度substr()
:返回子字符串sin()
:正弦cos()
:余弦sqrt()
:平方根rand()
:随机数
awk
内置函数的完整列表,可以查看手册。
例:toupper
1 | $ awk -F ':' '{ print toupper($1) }' demo.txt |
四、条件
awk
允许指定输出条件,只输出符合条件的行。
输出条件要写在动作的前面。
1 | $ awk '条件 动作' 文件名 |
请看下面的例子。print
命令前面是一个正则表达式,只输出包含usr
的行。
1 | $ awk -F ':' '/usr/ {print $1}' demo.txt |
下面的例子只输出奇数行,以及输出第三行以后的行。
1 | # 输出奇数行 |
下面的例子输出第一个字段等于指定值的行。
1 | $ awk -F ':' '$1 == "root" {print $1}' demo.txt |
五、if 语句
awk
提供了if
结构,用于编写复杂的条件。
1 | $ awk -F ':' '{if ($1 > "m") print $1}' demo.txt |
上面代码输出第一个字段的第一个字符大于m
的行。
if
结构还可以指定else
部分。
1 | $ awk -F ':' '{if ($1 > "m") print $1; else print "---"}' demo.txt |
六、相关连接
- An Awk tutorial by Example, Greg Grothaus
- 30 Examples for Awk Command in Text Processing, Mokhtar Ebrahim